package 计时器;

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.PriorityBlockingQueue;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: lenovo
 * Date: 2022-10-05
 * Time: 16:12
 */
class Task implements Comparable<Task>{//Task得放入到带有优先级的阻塞队列里,因此必须可比较的,实现Comparable接口
    //得有两个成员变量 1.指定执行的任务 2.delay执行的时间 转化为时间戳
    Runnable runnable;
    long time;
    public Task(Runnable runnable,long delay){
        this.runnable = runnable;
        this.time = System.currentTimeMillis()+delay;
    }

    @Override
    public int compareTo(Task o) {
        return (int)(time - o.time);
    }
}
class MyTMR{
    BlockingQueue<Task> queue = new PriorityBlockingQueue<>();
    public void schedule(Runnable runnable,long delay) throws InterruptedException {
        //当添加一个任务时,就得创建一个Task对象,并且将task放入到优先级阻塞队里里
       Task task = new Task(runnable,delay);

           queue.put(task);
        synchronized (this){
           notify();//唤醒else里的wait
       }

    }
    /*
    peek 如果先调用扫描线程,队列为空,peek会报空指针异常
     */
//    public MyTMR(){
//        Thread t = new Thread(){
//            @Override
//            public void run() {
//                synchronized (this){
//                    while (true){
//                        Task task = queue.peek();
//                        if(System.currentTimeMillis() >=task.time){
//                            task.runnable.run();
//                            try {
//                                queue.take();
//                            } catch (InterruptedException e) {
//                                e.printStackTrace();
//                            }
//                        }else{
//                            try {
//                                wait(System.currentTimeMillis()-task.time);
//                            } catch (InterruptedException e) {
//                                e.printStackTrace();
//                            }
//                        }
//
//                    }
//                }
//
//
//            }
//        };
//        t.start();
//    }
    //在优先级阻塞队列里有了task之后,worker扫描线程就可以持续扫描优先级阻塞队列了
    public  MyTMR(){
        Thread t = new Thread(){
            @Override
            public void run() {
                synchronized (this){
                    while(true){
                        try {
                            //取出队首元素
                            Task task = queue.take();
                            //判断队首元素的任务是否要执行
                    /*
                    当前时间大于或等于最初设定的时间就得执行任务了
                     */
                            if(System.currentTimeMillis()>=task.time){
                                task.runnable.run();
                            }else{//还未到达时间,将队首元素放回到队里,进行等待
                                queue.put(task);
                                //等待的时间:
                                wait(task.time - System.currentTimeMillis());
                                //如果有队列里有新的任务,queue.put后会唤醒wait,重新扫描优先级阻塞队列里的队首元素,如果有更早要执行的任务,那么等待的时间就会更新
                            }
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        };
        t.start();
    }

}
public class demo0 {
    public static void main(String[] args) throws InterruptedException {
        MyTMR mytimer = new MyTMR();
        mytimer.schedule(new Runnable() {
            @Override
            public void run() {
                System.out.println("这是任务1");
            }
        },3000);//3秒后执行
        mytimer.schedule(new Runnable() {
            @Override
            public void run() {
                System.out.println("这是任务2");
            }
        },4000);
        System.out.println("开始计时");
    }
}
